﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using QxFramework.Core;
using System;
namespace GameControl
{

public class ItemHealthManager : LogicModuleBase, IItemHealthManager, IPhysicalDamageManager,IMagicDamageManager
{
    Dictionary<string, float> itemsBlood = new Dictionary<string, float>();
    public static float EPS = 1e-6f;

        List<Tuple<string, string>> _ignorePairs = new List<Tuple<string, string>>();

        public List<Tuple<string, string>> IgnorePairs => _ignorePairs;

        public void DecreaseBlood(string name, float damage)
    {
        var blood = GetBloodAbout(name);
            damage = Mathf.Round(damage);
        if (blood <-EPS)
        {
            return;
        }
        else
        {
            blood -= damage;
            if (damage > EPS)
            {
                    ClockManager.Get<IItemSyncManager>().GetGameObjectByName(name).GetComponent<Item>().OnDamage(damage);
            }
            else
            {
                    ClockManager.Get<IItemSyncManager>().GetGameObjectByName(name).GetComponent<Item>().OnRecover(damage);
             }
            if ( blood< EPS)
            {
                    //       GameManager.Get<IItemInstantiateManager>().DestoryItemField(name);
                    MessageManager.Instance.Get<GameMap.ItemMapEvent>().DispatchMessage(GameMap.ItemMapEvent.DeleteInMap, this, new GameMap.ItemMapArgs {ItemName=name });
                itemsBlood.Remove(name);
            }
            else
            {
                    SetBloodAbout(name, blood);
            }
        }
    }

    public float GetBloodAbout(string name)
    {
        try
        {

            if (itemsBlood.ContainsKey(name) == false)
            {
                    itemsBlood[name] = GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(name).Blood;
            }
            return itemsBlood[name];
        }catch(System.Exception e)
        {
            Debug.LogWarning(e);
            return float.NegativeInfinity;
        }
    }
    public void SetBloodAbout(string name,float blood)
    {
        try
        {

            if (itemsBlood.ContainsKey(name) == false)
            {
                itemsBlood[name] = GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(name).Blood;
            }
            itemsBlood[name]=blood;
             
             GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(name).Blood = blood;
            /*unsafe
            {
                itemsBlood[name] = GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(name).Blood = blood;
            }*/

        }
        catch (System.Exception e)
        {
            Debug.LogWarning(e);
        //    return float.NegativeInfinity;
        }
    }

        public void OnCollisionHappen(string stressed, string stressing,float force)
        {
            if (stressed == default || stressing == default)
            {
                return;
            }
            if (CheckIfCanCollide(stressed, stressing) == false)
            {
                return;
            }
            //GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(stressed).Element 获取stressed材质;
            //        Debug.Log($"{this} {stressed} {stressing} {force}");
            try
            {

                 DecreaseBlood(stressed,Mathf.Max(0, force* GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(stressing).Sharpness - GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(stressed).Soildity*2)/10f);
            }
            catch (System.Exception e)
            {
                Debug.LogWarning(e);
            }
        }
        public void OnAttackHappen(string stressed,string stressing ,float power)
        {
            if (CheckIfCanCollide(stressed, stressing) == false)
            {
                return;
            }
            try
            {

                DecreaseBlood(stressed, Mathf.Max(1, power - GameManager.Get<IItemInstantiateManager>().GetItemFieldByName(stressed).MagicDefence));
            }
            catch (NullReferenceException e)
            {
                Debug.LogWarning(e);
            }
            catch(Exception e)
            {
                Debug.LogError(e);
            }
        }

        public bool CheckIfCanCollide(string stressed, string stressing)
        {
            if(_ignorePairs.Find(s => (s.Item1 == stressed && s.Item2 == stressing) || (s.Item2 == stressed && s.Item1 == stressing)) != null)
            {
                return false;
            }
            var a = _ignorePairs.FindAll(s => s.Item1 == stressed || s.Item2 == stressed);
            var b = _ignorePairs.FindAll(s => s.Item1 == stressing || s.Item2 == stressing);
            foreach(var x in a)
            {
                if (b.Find(s => s.Item1 == x.Item1 || s.Item2 == x.Item1)!=null)
                {
                    return false;
                }
                if (b.Find(s => s.Item1 == x.Item2 || s.Item2 == x.Item2) != null)
                {
                    return false;
                }
            }
            return true;
        }
    }
    public interface IItemHealthManager
    {
        float GetBloodAbout(string name);
        void DecreaseBlood(string name, float damage);
        List<Tuple<string, string>> IgnorePairs{ get; }

        bool CheckIfCanCollide(string stressed, string stressing);


}
public interface IPhysicalDamageManager
{
        void OnCollisionHappen(string stressed, string stressing,float force);
}
    public interface IMagicDamageManager
    {
        void OnAttackHappen(string stressed,string stressing, float power);
    }
}
public interface IFixedDamageManager
{
    void OnDamageHappen(string stressed, string stressing, float damage);
}